// $Id: qtui.cpp 52 2007-05-30 16:34:55Z DarkAn9el $
/***************************************************************************
 *   Copyright (C) 2007 by Andrea Blankenstijn, Ulrich Giraud              *
 *   <darkan9el@gmail.com>, <blade.124@laposte.net>                        *
 *                                                                         *
 *   Permission is hereby granted, free of charge, to any person obtaining *
 *   a copy of this software and associated documentation files (the       *
 *   "Software"), to deal in the Software without restriction, including   *
 *   without limitation the rights to use, copy, modify, merge, publish,   *
 *   distribute, sublicense, and/or sell copies of the Software, and to    *
 *   permit persons to whom the Software is furnished to do so, subject to *
 *   the following conditions:                                             *
 *                                                                         *
 *   The above copyright notice and this permission notice shall be        *
 *   included in all copies or substantial portions of the Software.       *
 *                                                                         *
 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       *
 *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    *
 *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
 *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR     *
 *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
 *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR *
 *   OTHER DEALINGS IN THE SOFTWARE.                                       *
 ***************************************************************************/

#include "qtui.h"
#include "../conversions.h"

QtUi::QtUi(QWidget *parent)
  : QWidget(parent)
{
  //// affichage ////
  display = new QLineEdit(); // QString::number(935, 36).toUpper()
  display->setReadOnly(false);
  display->setAlignment(Qt::AlignRight);

  //// clavier numérique ////
  QPushButton *digiButtons[10];
  QPushButton *dot = createButton(".");
  // TODO: afficher le caractère \u03c0 (π)
  QPushButton *pi = createButton("pi");

  for(short i=0; i<10; i++)
  {
      digiButtons[i] = createButton(QString::number(i));
  }

  // Positionnement en tableau des touches du clavier numérique
  QGridLayout *griddigits = new QGridLayout;

  griddigits->addWidget(digiButtons[7], 1, 0);
  griddigits->addWidget(digiButtons[8], 1, 1);
  griddigits->addWidget(digiButtons[9], 1, 2);

  griddigits->addWidget(digiButtons[4], 2, 0);
  griddigits->addWidget(digiButtons[5], 2, 1);
  griddigits->addWidget(digiButtons[6], 2, 2);

  griddigits->addWidget(digiButtons[1], 3, 0);
  griddigits->addWidget(digiButtons[2], 3, 1);
  griddigits->addWidget(digiButtons[3], 3, 2);

  griddigits->addWidget(digiButtons[0], 4, 0);
  griddigits->addWidget(dot, 4, 1);
  griddigits->addWidget(pi, 4, 2);

  //// Operateurs ////
  QPushButton *divis = createButton("\367"); // ÷
  QPushButton *times = createButton("\327"); // ×
  QPushButton *minus = createButton("-");
  QPushButton *plus = createButton("+");
  QPushButton *enter = createButton("ENTER", SLOT(execCalc()));
  QPushButton *lparanth = createButton("(");
  QPushButton *rparanth = createButton(")");
  QPushButton *power = createButton("^");

  QGridLayout *gridbase = new QGridLayout;

  gridbase->addWidget(power, 0, 0);
  gridbase->addWidget(lparanth, 0, 1);
  gridbase->addWidget(rparanth, 0, 2);
  gridbase->addWidget(divis, 0, 3);
  gridbase->addWidget(times, 1, 3);
  gridbase->addWidget(minus, 2, 3);
  gridbase->addWidget(plus, 3, 3);
  gridbase->addWidget(enter, 4, 3);

  gridbase->addLayout(griddigits, 1, 0, 4, 3);

  //// Fonctions ////
  QPushButton *sin = createButton("sin", SLOT(addFunction()));
  QPushButton *cos = createButton("cos", SLOT(addFunction()));
  QPushButton *tan = createButton("tan", SLOT(addFunction()));
  QPushButton *sqrt = createButton("sqrt", SLOT(addFunction())); // √

  QPushButton *asin = createButton("asin",  SLOT(addFunction()));
  QPushButton *acos = createButton("acos",  SLOT(addFunction()));
  QPushButton *atan = createButton("atan",  SLOT(addFunction()));
  QPushButton *log = createButton("log",  SLOT(addFunction()));

  QPushButton *ln = createButton("ln",  SLOT(addFunction()));

  //// Variables ////
  QPushButton *obase = createButton("obase", SLOT(add2Left()));
  QPushButton *ibase = createButton("ibase", SLOT(add2Left()));
  QPushButton *precision = createButton("precision", SLOT(add2Left()));

  //// Autres ////
  QPushButton *sci = createButton(tr("scientifique"), SLOT(displayMode(2)));
  QPushButton *flo = createButton(tr("flottant"), SLOT(displayMode(1)));
  QPushButton *constants = createButton(tr("constantes"), SLOT(selectConst()));
  QPushButton *clear = createButton("clear", SLOT(add2Right()));


  QGridLayout *gridadv = new QGridLayout;
  gridadv->setSizeConstraint(QLayout::SetFixedSize);

  gridadv->addWidget(sin, 3, 0);
  gridadv->addWidget(cos, 3, 1);
  gridadv->addWidget(tan, 3, 2);
  gridadv->addWidget(sqrt, 3, 3);

  gridadv->addWidget(asin, 2, 0);
  gridadv->addWidget(acos, 2, 1);
  gridadv->addWidget(atan, 2, 2);
  gridadv->addWidget(log, 2, 3);

  gridadv->addWidget(ln, 1, 0);

  gridadv->addWidget(obase, 1, 1);
  gridadv->addWidget(ibase, 1, 2);
  gridadv->addWidget(precision, 1, 3);

  gridadv->addWidget(sci, 0, 0);
  gridadv->addWidget(flo, 0, 1);
  gridadv->addWidget(constants, 0, 2);
  gridadv->addWidget(clear, 0, 3);


  QVBoxLayout *layout = new QVBoxLayout;

  layout->addWidget(display);
  layout->addLayout(gridadv);
  layout->addLayout(gridbase);
  setLayout(layout);
  setWindowTitle("ABC - QT GUI");
}

QPushButton *QtUi::createButton(const QString &text, const char *member)
{
  QPushButton *button = new QPushButton(text, this);
  connect(button, SIGNAL(clicked()), this, member);
  return button;
}

//// Slots ////
void QtUi::add2Right()
{
  QPushButton *clickedButton = qobject_cast<QPushButton *>(sender());
  QString value = clickedButton->text();
  if(value == "\367")
    display->setText(display->text() + '/');
  else if(value == "\327")
    display->setText(display->text() + '*');
  else if(value == "clear")
    display->clear();
  else
    display->setText(display->text() + value);
}

void QtUi::add2Left()
{
  QPushButton *clickedButton = qobject_cast<QPushButton *>(sender());
  QString value = clickedButton->text();
  display->setText(value + '=' + display->text());
}

void QtUi::addFunction()
{
  QPushButton *clickedButton = qobject_cast<QPushButton *>(sender());
  QString value = clickedButton->text();
  display->setText(display->text() + value + '(');
}

void QtUi::displayMode(short mode)
{
}

QString QtUi::selectConst()
{
  return "";
}

void QtUi::execCalc()
{
  Conversions bases;
  QString qstr = display->text();
  const char * chstr = qstr.toAscii();
  std::cin.putback('\n');
  for(short i=qstr.length()-1; i>=0; i--)
  {
    std::cin.putback(chstr[i]);
  }
  get_token();
  if(ReadTable("obase") == 10)
    display->setText(QString::number(expr(false)));
  else
    display->setText(
      QString::fromStdString
        ( bases.DecToX(expr(false), (ushort) ReadTable("obase")) )
    );
}
